<!DOCTYPE html>
<html>
<head>
<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?d890b1f16fb364253e79c5bb20225c3a";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>


    

    

    
<!-- Baidu Tongji -->
<script>var _hmt = _hmt || []</script>
<script async src="//hm.baidu.com/hm.js?busuanzi_value_site_uv"></script>
<!-- End Baidu Tongji -->




    <meta charset="utf-8">
    <meta name="baidu-site-verification" content="FYMCShbUK8" />
    <meta name="baidu-site-verification" content="ZYRF7OxQRW" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    <meta name="baidu-site-verification" content="cHSqtjI0PN" />
    
    
    <link rel="canonical" href="https://hhardyy.com/2019/09/30/webpack4-x/">
    
    
    <title>webpack4.x | 小方块 - hhardyy.com | 复杂的坑+归其原理+了解实现规则===解决？解决成功：加油解决成功;</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    
    <meta name="theme-color" content="#958e93">
    
    
    <meta name="keywords" content="webpack">
    <meta name="description" content="webpack4.x =&amp;gt; vue.config.js但是 !== vue.config.js">
<meta name="keywords" content="webpack">
<meta property="og:type" content="article">
<meta property="og:title" content="webpack4.x">
<meta property="og:url" content="http://yoursite.com/2019/09/30/webpack4-x/index.html">
<meta property="og:site_name" content="小方块 - hhardyy.com">
<meta property="og:description" content="webpack4.x =&amp;gt; vue.config.js但是 !== vue.config.js">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://yoursite.com/images/webpack/1.jpg">
<meta property="og:updated_time" content="2020-01-13T15:27:58.144Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="webpack4.x">
<meta name="twitter:description" content="webpack4.x =&amp;gt; vue.config.js但是 !== vue.config.js">
<meta name="twitter:image" content="http://yoursite.com/images/webpack/1.jpg">
    
        <link rel="alternate" type="application/atom+xml" title="小方块 - hhardyy.com" href="/atom.xml">
    
    <link rel="shortcut icon" href="/hardyfavicon.ico">
    <link rel="stylesheet" href="//unpkg.com/hexo-theme-material-indigo@latest/css/style.css">
    <script>window.lazyScripts=[]</script>

    <!-- custom head -->
    

</head>

<body>
    <div id="loading" class="active"></div>

    <aside id="menu" class="hide" >
  <div class="inner flex-row-vertical">
    <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menu-off">
        <i class="icon icon-lg icon-close"></i>
    </a>
    <div class="brand-wrap" style="background-image:url(/img/paulGraham.jpg)">
      <div class="brand" style="background-color:#4154b2">
        <a href="/" class="avatar waves-effect waves-circle waves-light">
          <img src="/img/avatar.jpg">
        </a>
        <hgroup class="introduce">
          <h5 class="nickname">BingZhenhuang</h5>
          <a href="mailto:huangbingzhen@hhardyy.com" title="huangbingzhen@hhardyy.com" class="mail">huangbingzhen@hhardyy.com</a>
        </hgroup>
      </div>
    </div>
    <div class="scroll-wrap flex-col">
      <ul class="nav">
        
            <li class="waves-block waves-effect">
              <a href="/"  >
                <i class="icon icon-lg icon-home"></i>
                主页
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/archives"  >
                <i class="icon icon-lg icon-archives"></i>
                所有文章
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/tags"  >
                <i class="icon icon-lg icon-tags"></i>
                标签
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://github.com/HHardyy" target="_blank" >
                <i class="icon icon-lg icon-github"></i>
                Github
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://gitee.com/hhardyy" target="_blank" >
                <i class="icon icon-lg icon-cloud"></i>
                Gitee
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://juejin.im/user/59a26f926fb9a02487553b04"  >
                <i class="icon icon-lg icon-pencil"></i>
                掘金-圳
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://segmentfault.com/u/hhardyy"  >
                <i class="icon icon-lg icon-comments"></i>
                Segmentfault
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://codepen.io/HHardyy/" target="_blank" >
                <i class="icon icon-lg icon-codepen"></i>
                Codepen
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="https://www.freecodecamp.cn/hhardyy" target="_blank" >
                <i class="icon icon-lg icon-leaf"></i>
                Freecodecamp
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/友情链接"  >
                <i class="icon icon-lg icon-link"></i>
                友链
              </a>
            </li>
        
      </ul>
    </div>
  </div>
</aside>

    <main id="main">
        <header class="top-header" id="header">
    <div class="flex-row">
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light on" id="menu-toggle">
          <i class="icon icon-lg icon-navicon"></i>
        </a>
        <div class="flex-col header-title ellipsis">webpack4.x</div>
        
        <div class="search-wrap" id="search-wrap">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
                <i class="icon icon-lg icon-chevron-left"></i>
            </a>
            <input type="text" id="key" class="search-input" autocomplete="off" placeholder="输入感兴趣的关键字">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="search">
                <i class="icon icon-lg icon-search"></i>
            </a>
        </div>
        
        
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menuShare">
            <i class="icon icon-lg icon-share-alt"></i>
        </a>
        
    </div>
</header>
<header class="content-header post-header">

    <div class="container fade-scale">
        <h1 class="title">webpack4.x</h1>
        <h5 class="subtitle">
            
                <time datetime="2019-09-30T14:37:59.000Z" itemprop="datePublished" class="page-time">
  2019-09-30
</time>


            
        </h5>
    </div>

    


</header>


<div class="container body-wrap">
    
    <aside class="post-widget">
        <nav class="post-toc-wrap" id="post-toc">
            <h4>TOC</h4>
            <ol class="post-toc"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#install"><span class="post-toc-number">1.</span> <span class="post-toc-text">install</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#mode"><span class="post-toc-number">2.</span> <span class="post-toc-text">mode</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#sourcemap"><span class="post-toc-number">3.</span> <span class="post-toc-text">sourcemap</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#entry"><span class="post-toc-number">4.</span> <span class="post-toc-text">entry</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#output"><span class="post-toc-number">4.1.</span> <span class="post-toc-text">output</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#module"><span class="post-toc-number">5.</span> <span class="post-toc-text">module</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#plugins"><span class="post-toc-number">6.</span> <span class="post-toc-text">plugins</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#devServer"><span class="post-toc-number">7.</span> <span class="post-toc-text">devServer</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#hot"><span class="post-toc-number">7.1.</span> <span class="post-toc-text">hot</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#host"><span class="post-toc-number">7.2.</span> <span class="post-toc-text">host</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#port"><span class="post-toc-number">7.3.</span> <span class="post-toc-text">port</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#open"><span class="post-toc-number">7.4.</span> <span class="post-toc-text">open</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#contentBase"><span class="post-toc-number">7.5.</span> <span class="post-toc-text">contentBase</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#proxy配置代理，处理本地跨域，"><span class="post-toc-number">7.6.</span> <span class="post-toc-text">proxy配置代理，处理本地跨域，</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#pathRewrite"><span class="post-toc-number">7.7.</span> <span class="post-toc-text">pathRewrite</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#HotModuleReplacementPlugin"><span class="post-toc-number">8.</span> <span class="post-toc-text">HotModuleReplacementPlugin</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#两种配置bable的方案"><span class="post-toc-number">9.</span> <span class="post-toc-text">两种配置bable的方案</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#一"><span class="post-toc-number">9.1.</span> <span class="post-toc-text">一</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#二"><span class="post-toc-number">9.2.</span> <span class="post-toc-text">二</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#three-shaking"><span class="post-toc-number">10.</span> <span class="post-toc-text">three shaking</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#HMR模块热替换"><span class="post-toc-number">11.</span> <span class="post-toc-text">HMR模块热替换</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#性能优化"><span class="post-toc-number">12.</span> <span class="post-toc-text">性能优化</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#code-splitting"><span class="post-toc-number">12.1.</span> <span class="post-toc-text">code splitting</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#webapck分析工具"><span class="post-toc-number">12.2.</span> <span class="post-toc-text">webapck分析工具</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#优化"><span class="post-toc-number">12.3.</span> <span class="post-toc-text">优化</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#css代码分割"><span class="post-toc-number">12.4.</span> <span class="post-toc-text">css代码分割</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#css代码压缩"><span class="post-toc-number">12.5.</span> <span class="post-toc-text">css代码压缩</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#缓存"><span class="post-toc-number">12.6.</span> <span class="post-toc-text">缓存</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#shimming的作用"><span class="post-toc-number">13.</span> <span class="post-toc-text">shimming的作用</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#模块this"><span class="post-toc-number">14.</span> <span class="post-toc-text">模块this</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#全局变量"><span class="post-toc-number">15.</span> <span class="post-toc-text">全局变量</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#如何开发一个库"><span class="post-toc-number">16.</span> <span class="post-toc-text">如何开发一个库</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#externals"><span class="post-toc-number">17.</span> <span class="post-toc-text">externals</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#PWA"><span class="post-toc-number">18.</span> <span class="post-toc-text">PWA</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#ts打包配置"><span class="post-toc-number">19.</span> <span class="post-toc-text">ts打包配置</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#eslint"><span class="post-toc-number">20.</span> <span class="post-toc-text">eslint</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#webpack性能优化"><span class="post-toc-number">21.</span> <span class="post-toc-text">webpack性能优化</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#跟上技术的迭代-升级webpack，npm-yarn-node"><span class="post-toc-number">21.1.</span> <span class="post-toc-text">跟上技术的迭代   升级webpack，npm|yarn|node</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#尽可能少的模块使用loader"><span class="post-toc-number">21.2.</span> <span class="post-toc-text">尽可能少的模块使用loader</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#Plugin尽可能精简并确保可靠"><span class="post-toc-number">21.3.</span> <span class="post-toc-text">Plugin尽可能精简并确保可靠</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#插件DellPlugin提高打包速率"><span class="post-toc-number">21.4.</span> <span class="post-toc-text">插件DellPlugin提高打包速率</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#控制包大小"><span class="post-toc-number">21.5.</span> <span class="post-toc-text">控制包大小</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#thread-loader-parallel-webpack-happypack多进程打包（利用node里面的多进程，使用多个cpu）"><span class="post-toc-number">21.6.</span> <span class="post-toc-text">thread-loader,parallel-webpack,happypack多进程打包（利用node里面的多进程，使用多个cpu）</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#合理使用sourceMap"><span class="post-toc-number">21.7.</span> <span class="post-toc-text">合理使用sourceMap</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#综合stats分析打包结果"><span class="post-toc-number">21.8.</span> <span class="post-toc-text">综合stats分析打包结果</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#开发环境内存编译"><span class="post-toc-number">21.9.</span> <span class="post-toc-text">开发环境内存编译</span></a></li></ol></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#打包多页面，"><span class="post-toc-number">22.</span> <span class="post-toc-text">打包多页面，</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#如何编写一个loader"><span class="post-toc-number">23.</span> <span class="post-toc-text">如何编写一个loader</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#编写一个plugin"><span class="post-toc-number">24.</span> <span class="post-toc-text">编写一个plugin</span></a></li></ol>
        </nav>
    </aside>
    
<article id="post-webpack4-x"
  class="post-article article-type-post fade" itemprop="blogPost">

    <div class="post-card">
        <h1 class="post-card-title">webpack4.x</h1>
        <div class="post-meta">
            <time class="post-time" title="2019-09-30 22:37:59" datetime="2019-09-30T14:37:59.000Z"  itemprop="datePublished">2019-09-30</time>

            


            

        </div>
        <div class="post-content" id="post-content" itemprop="postContent">
            <p>webpack4.x =&gt; vue.config.js但是 !== vue.config.js</p>
<p><iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=1369794434&auto=0&height=66"></iframe><br><a id="more"></a></p>
<p>为什么要用webpack，你用的脚手架大部分都是基于这个东西，而这个东西基于nodejs，而nodejs依赖v8引擎，而v8引擎就是v8引擎。</p>
<blockquote>
<p>webpack4.x从安装开始</p>
</blockquote>
<h3 id="install"><a href="#install" class="headerlink" title="install"></a>install</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install webpack -webpack-cli -D</div></pre></td></tr></table></figure>
<p>解释：为什么webpack和webpack-cli需要分开安装，在webpack3中，webpack本身和它的CLI以前都是在同一个包中，但在第4版中已经将两者分开来更好地管理它们。webpack建议装在局部环境，虽然装在全局比较方便，但是当多个项目使用的webpack版本不一样的时候就会出现问题，即使把每个项目的webpack版本都改成一样的，又会导致原本的项目出问题，所以还是建议安装在局部环境，每个项目有独立的webpack。</p>
<h3 id="mode"><a href="#mode" class="headerlink" title="mode"></a>mode</h3><p>production：生产模式，线上的环境<br>development：开发模式，开发环境</p>
<h3 id="sourcemap"><a href="#sourcemap" class="headerlink" title="sourcemap"></a>sourcemap</h3><p><a href="https://www.webpackjs.com/configuration/devtool/" target="_blank" rel="external">官网介绍</a><br>mode  development  ‘cheap-module-eval-souce-map’    提示比较强，打包速度比较快<br>mode production  ‘cheap-module-souce-map’</p>
<h3 id="entry"><a href="#entry" class="headerlink" title="entry"></a>entry</h3><p>入口：每个 HTML 页面都有一个入口起点。单页应用(SPA)：一个入口起点，多页应用(MPA)：多个入口起点。<br>单个文件打包：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">entry:<span class="string">"index.js"</span></div></pre></td></tr></table></figure></p>
<p>多个文件打包成多个：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">entry:&#123;</div><div class="line">   one:<span class="string">'index1.js'</span>,</div><div class="line">   two:<span class="string">'index2.js'</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>多个文件打包成单个：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">entry: &#123;</div><div class="line">  main:[<span class="string">"index1.js"</span>,<span class="string">"index2.js"</span>]</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>动态入口：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">entry: <span class="function"><span class="params">()</span> =&gt;</span> <span class="string">'index.js'</span></div></pre></td></tr></table></figure></p>
<p>多个动态入口：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">entry: <span class="function"><span class="params">()</span> =&gt;</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve</span>) =&gt;</span> resolve([<span class="string">'index1.js'</span>, <span class="string">'index2.js'</span>]))</div></pre></td></tr></table></figure></p>
<h4 id="output"><a href="#output" class="headerlink" title="output"></a>output</h4><p>出口：output 位于对象最顶级键(key)，包括了一组选项，指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」。output需要依赖node的path模块来指定当前项目的根目录。<br>单页面应用的输出：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">output:&#123;</div><div class="line">	path:path.resolve(__dirname,<span class="string">'dist'</span>),   <span class="comment">//输出目录</span></div><div class="line">	filename:<span class="string">'bundle'</span>  <span class="comment">//输出文件名</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>多页面输出：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">output:&#123;</div><div class="line">	 filename: <span class="string">'[name].bundle.js'</span>,</div><div class="line">    path: path.resolve(__dirname, <span class="string">'dist'</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>[name]是根据入口entry设置的变量来输出对应的文件名<br>配置项大概这么多：<br>filename，输出的文件名，可以自定义一些名称规则<br>path，配置输出文件存放在本地的目录<br>publicPath，配置CDN的路径<br>chunkFilename ，处理异步加载时的命名规则<br>hash、chunkhash和contenthash三者的区别<br>hash是项目级别的，每次构建得出的hash都是相同的，这可能不利于文件的缓存<br>chunkhash是文件级别的，值是变动修改的文件的chunkhash值<br>contenthash是文件级别的，在拆分css文件时记得使用处理css的缓存</p>
<h3 id="module"><a href="#module" class="headerlink" title="module"></a>module</h3><p>模块：决定了如何处理项目中的不同类型的模块。防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用，或任何其他导入机制。忽略大型的 library 可以提高构建性能。这个参数还是有挺多的，可以去官网看<br>比如在安装完webpack之后项目目录中肯定多了一个叫node_modules的文件夹，里头有很多模块是不需要打包的，同时要识别jsx文件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">rules: [&#123;</div><div class="line">   test: <span class="regexp">/\.tsx?$/</span>,</div><div class="line">   use: <span class="string">'ts-loader'</span>,</div><div class="line">   exclude: <span class="regexp">/node_modules/</span></div><div class="line">&#125;]</div></pre></td></tr></table></figure></p>
<h3 id="plugins"><a href="#plugins" class="headerlink" title="plugins"></a>plugins</h3><p>插件：plugins 选项用于以各种方式自定义 webpack 构建过程。webpack 附带了各种内置插件，可以通过 webpack.[plugin-name] 访问这些插件。请查看这个页面获取插件列表和对应文档，但请注意这只是其中一部分，社区中还有许多插件。比如我们做脚手架一定会用到的<a href="https://github.com/jantimon/html-webpack-plugin" target="_blank" rel="external">html-webpack-plugin</a>,可以去看一下它的Options，就可以根据业务来做脚手架了，使用也简单，install之后引入之后<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">plugins: [</div><div class="line">  <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</div><div class="line">    ...options</div><div class="line">  &#125;)</div><div class="line">]</div></pre></td></tr></table></figure></p>
<h3 id="devServer"><a href="#devServer" class="headerlink" title="devServer"></a>devServer</h3><p>开发环境下的一个内置小型本地服务器: 基于nodejs实现的服务器，你也可以自己写一个，就像这样<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>)</div><div class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>)</div><div class="line"><span class="keyword">const</span> webpackDevMiddleware = <span class="built_in">require</span>(<span class="string">'webpack-dev-middleware'</span>)</div><div class="line"><span class="keyword">const</span> config = <span class="built_in">require</span>(<span class="string">'./webpack.config.js'</span>)</div><div class="line"><span class="keyword">const</span> conplier = webpack(config)</div><div class="line"></div><div class="line"><span class="keyword">const</span> app = express()</div><div class="line">app.use(webpackDevMiddleware(conplier,&#123;&#125;))</div><div class="line">app.listen(<span class="number">9090</span>,()=&gt;&#123;</div><div class="line">	<span class="built_in">console</span>.log(<span class="string">'at 9090'</span>)</div><div class="line">&#125;)</div></pre></td></tr></table></figure></p>
<p>devServer是用来提高开发效率的，它提供了一些配置项，可以用于改变devServer的默认行为，要配置devServer，除了可以在配置文件里通过devServer传入参数，还可以通过命令行传入参数。</p>
<p>⚠️注意！！！只有在通过devServer启动webpack时，配置文件里的devServer才会生效，因为这些参数所对应的功能都是devServer提供的，webpack本身并不认识devServer的配置项。</p>
<h4 id="hot"><a href="#hot" class="headerlink" title="hot"></a>hot</h4><p>hot配置是否启用模块的热替换功能，开启之后代码变动会自动刷新页面，做到实时热更新<br>两种配置方法：<br>1、webpack.config.js里头的devServer设置hot为true或者false,需要引入一个热更新插件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">plugins: [</div><div class="line">     <span class="keyword">new</span> webpack.HotModuleReplacementPlugin(), </div><div class="line">],</div></pre></td></tr></table></figure></p>
<p>2、命令行，在package.json中的script中，比如原本用来启动本地项目的命令后面加上–hot<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="string">"start"</span>: <span class="string">"NODE_ENV=development  webpack-dev-server --config  webpack.develop.config.js"</span></div></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="string">"start"</span>: <span class="string">"NODE_ENV=development  webpack-dev-server --config  webpack.develop.config.js --hot"</span></div></pre></td></tr></table></figure>
<h4 id="host"><a href="#host" class="headerlink" title="host"></a>host</h4><p>devServer服务监听的地址，如果想让局域网内的其他用户访问本项目，可以将host配置为本机的IP，通过命令行 –host 0.0.0.0也可以</p>
<h4 id="port"><a href="#port" class="headerlink" title="port"></a>port</h4><p>端口：如8080,9090</p>
<h4 id="open"><a href="#open" class="headerlink" title="open"></a>open</h4><p>是否打开默认浏览器，如果配置了open，在run start之后会打开默认浏览器，也可以在命令行  –open</p>
<h4 id="contentBase"><a href="#contentBase" class="headerlink" title="contentBase"></a>contentBase</h4><p>配置devServer，Http服务器的文件根目录</p>
<h4 id="proxy配置代理，处理本地跨域，"><a href="#proxy配置代理，处理本地跨域，" class="headerlink" title="proxy配置代理，处理本地跨域，"></a>proxy配置代理，处理本地跨域，</h4><h4 id="pathRewrite"><a href="#pathRewrite" class="headerlink" title="pathRewrite"></a>pathRewrite</h4><p>这个的应用场景是，比如项目里面写了个a.json，突然接口有问题需要换到测试接口b.json，就用这个代理<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">devServer: &#123;</div><div class="line">	contentBase: <span class="string">'./dist'</span>,</div><div class="line">	open: <span class="literal">true</span>,</div><div class="line">	port: <span class="number">8090</span>,</div><div class="line">	hot: <span class="literal">true</span>,</div><div class="line">	historyApiFallback: <span class="literal">true</span>,</div><div class="line">	proxy: &#123;</div><div class="line">		<span class="string">'/react/api'</span>: &#123;</div><div class="line">			target: <span class="string">'http://hhardyy.com'</span>,</div><div class="line">			pathRewrite: &#123;</div><div class="line">				<span class="string">'a.json'</span>: <span class="string">'b.json'</span></div><div class="line">			&#125;</div><div class="line">		&#125;</div><div class="line">	&#125;</div><div class="line">&#125;,</div></pre></td></tr></table></figure></p>
<p>devServer.historyApiFallback，   解决单页面应用无法跳转的问题，比如Route 的path=/list ,localhost:8080/list打不开</p>
<h3 id="HotModuleReplacementPlugin"><a href="#HotModuleReplacementPlugin" class="headerlink" title="HotModuleReplacementPlugin"></a>HotModuleReplacementPlugin</h3><p>这个插件css修改了也不会重新渲染刷新整个页面，只是把css即时修改<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> webpack= <span class="built_in">require</span>(<span class="string">'webpack'</span>)</div><div class="line">plugins:[</div><div class="line">    <span class="keyword">new</span> webpack.HotModuleReplacementPlugin()</div><div class="line">]</div></pre></td></tr></table></figure></p>
<h3 id="两种配置bable的方案"><a href="#两种配置bable的方案" class="headerlink" title="两种配置bable的方案"></a>两种配置bable的方案</h3><h4 id="一"><a href="#一" class="headerlink" title="一"></a>一</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line">	test: <span class="regexp">/\.js$/</span>,</div><div class="line">	exclude: <span class="regexp">/node_modules/</span>,</div><div class="line">	loader: <span class="string">'babel-loader'</span>,</div><div class="line">	options: &#123;</div><div class="line">		presets: [[</div><div class="line">		<span class="string">'@babel/preset-env'</span>,         <span class="comment">//需要在index.js中去import "@babel/polyfill";</span></div><div class="line">		&#123;</div><div class="line">		 	targets: &#123;</div><div class="line">		        edge: <span class="string">"17"</span>,</div><div class="line">		        firefox: <span class="string">"60"</span>,</div><div class="line">		        chrome: <span class="string">"67"</span>,</div><div class="line">		       safari: <span class="string">"11.1"</span>,</div><div class="line">		     &#125;,</div><div class="line">		 	useBuiltIns: <span class="string">'usage'</span>                     <span class="comment">//配置了这个的话，代码里面不用单独引入babel-polifill，它已经自动安装了</span></div><div class="line">		 &#125;</div><div class="line">	    ]]</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="二"><a href="#二" class="headerlink" title="二"></a>二</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="string">"plugins"</span>: [</div><div class="line">	    [</div><div class="line">	      <span class="string">"@babel/plugin-transform-runtime"</span>,</div><div class="line">	      &#123;</div><div class="line">	        <span class="string">"absoluteRuntime"</span>: <span class="literal">false</span>,</div><div class="line">	        <span class="string">"corejs"</span>: <span class="literal">false</span>,</div><div class="line">	        <span class="string">"helpers"</span>: <span class="literal">true</span>,</div><div class="line">	        <span class="string">"regenerator"</span>: <span class="literal">true</span>,</div><div class="line">	        <span class="string">"useESModules"</span>: <span class="literal">false</span></div><div class="line">	      &#125;</div><div class="line">	    ]</div><div class="line">	  ]</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h3 id="three-shaking"><a href="#three-shaking" class="headerlink" title="three shaking"></a>three shaking</h3><p>顾名思义是摇树的意思：将一些模块中引入不用的方法摇掉，只支持import使用，因为import的底层是静态引入的方式，commonjs是动态引入的方式，开发环境（mode:development）使用three shaking要加上<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">optimization:&#123;</div><div class="line">    usedExports: <span class="literal">true</span>     <span class="comment">//哪些模块被使用了再做打包 </span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>package.json加上<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="string">"sideEffects"</span>:<span class="literal">false</span></div></pre></td></tr></table></figure></p>
<p>假如在某个js文件内import “@babel/polly-fill”,那three<br>shaking发现它没有导出模块，在打包的时候会被忽略掉，但是需要使用里头的东西，为了避免打包错误，需要添加这个配置<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="string">"sideEffects"</span>:[<span class="string">"@babel/polly-fill"</span>]</div></pre></td></tr></table></figure></p>
<p>false的意思是对所有的模块都进行three shaking，没有特殊处理的模块.一般如果在模块中导入了css文件，three shaking会去检测有没有模块导出，所以一般sideEffects会配置[“*.css”]</p>
<p>在开发环境下three shaking不会去删除没有用到的模块，因为在开发环境需要调试，如果打包上线的话three shaking其实自动就配置好了，甚至都不需要写three shaking配置。</p>
<h3 id="HMR模块热替换"><a href="#HMR模块热替换" class="headerlink" title="HMR模块热替换"></a>HMR模块热替换</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">new</span> webpack.HotModuleReplacementPlugin()   <span class="comment">//启用 webpack 内置的 HMR插件</span></div><div class="line"></div><div class="line"><span class="keyword">if</span> (<span class="built_in">module</span>.hot) &#123;</div><div class="line">    <span class="built_in">module</span>.hot.accept(<span class="string">'./print.js'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123; <span class="comment">//告诉 webpack 接受热替换的模块</span></div><div class="line">        <span class="built_in">console</span>.log(<span class="string">'Accepting the updated printMe module!'</span>);</div><div class="line">        printMe();</div><div class="line">    &#125;)</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h3 id="性能优化"><a href="#性能优化" class="headerlink" title="性能优化"></a>性能优化</h3><h4 id="code-splitting"><a href="#code-splitting" class="headerlink" title="code splitting"></a>code splitting</h4><p>代码分割<br>同步代码：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">optimization: &#123;</div><div class="line">   splitChunks: &#123;</div><div class="line">       chunks: <span class="string">'all'</span></div><div class="line">   &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>异步代码：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install --save-dev @babel/plugin-syntax-dynamic-<span class="keyword">import</span></div></pre></td></tr></table></figure></p>
<p>.babelrc<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">plugins:[<span class="string">"dynamic-import-webpack"</span>]</div></pre></td></tr></table></figure></p>
<p>index.js<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">getComponent</span>(<span class="params"></span>) </span>&#123;</div><div class="line">	<span class="keyword">return</span> <span class="keyword">import</span>(<span class="comment">/*webpackChunkName:"lodash"*/</span><span class="string">'lodash'</span>).then((&#123;</div><div class="line">		<span class="keyword">default</span>: _</div><div class="line">	&#125;) =&gt; &#123;</div><div class="line">		<span class="keyword">let</span> element = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>)</div><div class="line">		element.innerHTML = _.join([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">5</span>, <span class="number">5</span>, <span class="number">5</span>, <span class="number">5</span>], <span class="string">'***'</span>)</div><div class="line">		<span class="keyword">return</span> element</div><div class="line">	&#125;)</div><div class="line">&#125;</div><div class="line"></div><div class="line">getComponent().then(<span class="function"><span class="params">element</span> =&gt;</span> &#123;</div><div class="line">	<span class="built_in">document</span>.body.appendChild(element)</div><div class="line">&#125;)</div></pre></td></tr></table></figure></p>
<h4 id="webapck分析工具"><a href="#webapck分析工具" class="headerlink" title="webapck分析工具"></a>webapck分析工具</h4><p><a href="github.com/webpack/analyse">git仓库</a><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">--profile --json &gt; stats.json     <span class="comment">//把打包过程的一些解释放到一个json文件里</span></div></pre></td></tr></table></figure></p>
<p>打包分析： <a href="https://webpack.js.org/guides/code-splitting/#bundle-analysis" target="_blank" rel="external">https://webpack.js.org/guides/code-splitting/#bundle-analysis</a></p>
<h4 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h4><p>在首屏主要代码加载完毕然后释放出网络之后再去加载模态框等其他代码用Prefetching  /  Preloading modules，<br>前端性能优化的时候，缓存其实不是最主要的点，而最主要的点应该是放到代码覆盖率上</p>
<h4 id="css代码分割"><a href="#css代码分割" class="headerlink" title="css代码分割"></a>css代码分割</h4><p><a href="https://webpack.js.org/plugins/mini-css-extract-plugin/#root" target="_blank" rel="external">可以看一下这里</a><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">output: &#123;</div><div class="line">		filename: <span class="string">'[name].js'</span>,</div><div class="line">		chunkFilename: <span class="string">'[name].chunk.js'</span>,        <span class="comment">//加上这个，然后用上下面的插件</span></div><div class="line">		path: path.resolve(__dirname, <span class="string">'../dist'</span>)</div><div class="line">	&#125;</div><div class="line"></div><div class="line">plugins  : MiniCssExtractPlugin</div></pre></td></tr></table></figure></p>
<p>例如在index.js里面import 1.css和import 2.css,跑起来的时候就会将1.css和2.css合并到main.css里面，<br>只能用在生产环境，因为不支持HMR，用在开发环境的话会影响开发效率。</p>
<h4 id="css代码压缩"><a href="#css代码压缩" class="headerlink" title="css代码压缩"></a>css代码压缩</h4><p>用optimize-css-assets-webpack-plugin这个插件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install optimize-css-assets-webpack-plugin -D</div></pre></td></tr></table></figure></p>
<p>使用方法：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> OptimizeCSSAssetsPlugin = <span class="built_in">require</span>(<span class="string">'optimize-css-assets-webpack-plugin'</span>);</div><div class="line">optimization: &#123;</div><div class="line">	minimizer: [<span class="keyword">new</span> OptimizeCSSAssetsPlugin(&#123;&#125;)],</div><div class="line">&#125;,</div></pre></td></tr></table></figure></p>
<p>假如要把index.js和index1.js和indexn.js中引用的css文件单独分割到styles文件里面<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">optimization:&#123;</div><div class="line">    splitChunks: &#123;</div><div class="line">		cacheGroups: &#123;</div><div class="line">		  styles: &#123;</div><div class="line">			name: <span class="string">'styles'</span>,</div><div class="line">			test: <span class="regexp">/\.css$/</span>,</div><div class="line">			chunks: <span class="string">'all'</span>,</div><div class="line">			enforce: <span class="literal">true</span>,      <span class="comment">//忽略掉所有默认配置</span></div><div class="line">		  &#125;,</div><div class="line">		&#125;,</div><div class="line">	  &#125;,</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>performance:false    //不让提示性能上的问题</p>
<h4 id="缓存"><a href="#缓存" class="headerlink" title="缓存"></a>缓存</h4><p>每次webpack打包的文件放到服务器，第二次请求服务器会默认请求缓存<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">output: &#123;</div><div class="line">	filename: <span class="string">'[name].[contenthash].js'</span>,</div><div class="line">	chunkFilename: <span class="string">'[name].[contenthash].js'</span>,</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>这么配置之后如果源代码没有改变，那么打包生成的cantenthash永远不变，根据content产生的hash字符串,老版本webpack如果发现没改变代码但是打包的hash值不一样，这时候需要做额外配置<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">optimization: &#123;</div><div class="line">	runtimeChunk: &#123;</div><div class="line">		name: <span class="string">'runtime'</span></div><div class="line">	&#125;,</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>在用webpack打包的时候，main.js放的是业务逻辑，vendors放的是用的库，比如jquery，然后main.js和vendors其实是有关联的，处理这些关联的内置代码是manifest,默认存在两个文件里面，它在每次打包的时候在旧版有差异，正是这些差异导致在打包的时候虽然没有改动源代码，但是两个文件里面的manifest实际上已经跟着变了。</p>
<h3 id="shimming的作用"><a href="#shimming的作用" class="headerlink" title="shimming的作用"></a>shimming的作用</h3><p>比如在index.js文件里<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> $ <span class="keyword">from</span> <span class="string">'jquery'</span></div><div class="line"><span class="keyword">import</span> &#123; ui &#125; <span class="keyword">from</span> <span class="string">'jquery.ui.js'</span></div></pre></td></tr></table></figure></p>
<p>其中jquery.ui.js<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">ui</span>(<span class="params"></span>)</span>&#123;</div><div class="line">   $(<span class="string">'body'</span>).css(<span class="string">'background'</span>,<span class="string">'red'</span>)</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>打包之后会报错说$未定义，因为每个模块只能使用模块内部的代码,那如果有一个库，又想用又不能修改内部的代码，就可以利用webpack自带的api<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> webpack <span class="keyword">from</span> <span class="string">'webpack'</span></div><div class="line">plugins:[</div><div class="line">    <span class="keyword">new</span> webpack.ProviderPlugin(&#123;</div><div class="line">        $:jquery</div><div class="line">    &#125;)</div><div class="line">]</div></pre></td></tr></table></figure></p>
<p>意思就是模块内发现使用$的时候，就自动引入jquery</p>
<h3 id="模块this"><a href="#模块this" class="headerlink" title="模块this"></a>模块this</h3><p>如果想让加载的模块this指向window而不是自己（默认指向自己）<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install imports-loader --save-dev</div></pre></td></tr></table></figure></p>
<p>然后再在test 的.js文件使用loader<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">test:<span class="regexp">/\.js$/</span>,</div><div class="line">exclude:<span class="regexp">/node_modules/</span>,</div><div class="line">use:[</div><div class="line">    &#123;</div><div class="line">       loader:<span class="string">'babel-loader'</span></div><div class="line">    &#125;,</div><div class="line">    &#123;</div><div class="line">       loader:<span class="string">'imports-loader?this=&gt;window'</span></div><div class="line">    &#125;</div><div class="line">]</div></pre></td></tr></table></figure></p>
<h3 id="全局变量"><a href="#全局变量" class="headerlink" title="全局变量"></a>全局变量</h3><p>如何在webpack打包的过程中使用全局变量<br>分两个环境<br>webpack.prod.js  ＆＆　webpack.dev.js  &amp;&amp; webpack.comm.js(公共配置)<br>1、module.exports = prodConfig<br>2、module.exports = devConfig<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">let</span> merge = <span class="built_in">require</span>(<span class="string">'webpack-merge'</span>)</div><div class="line"><span class="keyword">let</span> commConfig = &#123;</div><div class="line">   ...公共webpack配置</div><div class="line">&#125;</div><div class="line"><span class="built_in">module</span>.exports = <span class="function">(<span class="params">env</span>)=&gt;</span>&#123;</div><div class="line">   <span class="keyword">if</span>( env &amp;&amp; env.production === <span class="string">'hardy'</span> )&#123;</div><div class="line">       <span class="keyword">return</span> merge(commConfig, prodConfig)</div><div class="line">   &#125;<span class="keyword">else</span>&#123;</div><div class="line">       <span class="keyword">return</span> merge(commConfig, devConfig)</div><div class="line">   &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>env是package.json传入的全局变量，例如package.json里头的打包命令设置为<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="string">"dev"</span>:<span class="string">"webpack-dev-server --config ./build/webpack.comm.js"</span></div><div class="line"><span class="string">"build"</span> : <span class="string">"webpack --env.production==='hardy' --config ./build/webpack.comm.js"</span></div></pre></td></tr></table></figure></p>
<h3 id="如何开发一个库"><a href="#如何开发一个库" class="headerlink" title="如何开发一个库"></a>如何开发一个库</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">output: &#123;</div><div class="line">    path: path.resolve(__dirname, <span class="string">'dist'</span>),</div><div class="line">    filename: <span class="string">'library.js'</span>,</div><div class="line">    library:<span class="string">'library'</span>,</div><div class="line">    libraryTarget: <span class="string">'umd'</span>   </div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>libraryTarget: ‘umd’   =&gt;<br>import library from ‘library.js’   ES6<br>const library = require(‘library’)  Common<br>require([‘library’,function()])   AMD<br> library:’library’ =&gt;支持script引入方式  意思就是打包生成的js文件挂载到页面的全局变量中然后直接library.调用里头的方法</p>
<h3 id="externals"><a href="#externals" class="headerlink" title="externals"></a>externals</h3><p>可以是字符串，数组，对象<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">externals: [<span class="string">'lodash'</span>]</div></pre></td></tr></table></figure></p>
<p>防止用户在import 再打包的时候项目中有两个lodash，不过打包之后没有lodash，需要自己引入<br>,就是当lodash被commonjs的方式引入的时候，名字必须是lodash，也就是const lodash = require(‘lodash’),而不能写成const _ = require(‘lodash’)<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">externals: &#123;</div><div class="line">    lodash: &#123;</div><div class="line">        commonjs:<span class="string">'lodash'</span></div><div class="line">    &#125;</div><div class="line">&#125;,</div></pre></td></tr></table></figure></p>
<p>root的作用是当以script src的方式引入的时候页面上必须注册一个名为_的全局变量<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">externals: &#123;</div><div class="line">    lodash: &#123;</div><div class="line">        root: <span class="string">'_'</span>,      </div><div class="line">        commonjs: <span class="string">'lodash'</span></div><div class="line">    &#125;</div><div class="line">&#125;,</div></pre></td></tr></table></figure></p>
<h3 id="PWA"><a href="#PWA" class="headerlink" title="PWA"></a>PWA</h3><p>Progressive Web Application    ===    PWA  =&gt;遇到断网的情况下依然可以访问,用户体验更好<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install workbox-webpack-plugin --save-dev</div></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> workboxWebpackPlugin = <span class="built_in">require</span>(<span class="string">'"workbox-webpack-plugin"'</span>)</div><div class="line"></div><div class="line"><span class="keyword">new</span> workboxWebpackPlugin.GenerateSW(&#123;</div><div class="line">	clientsClaim: <span class="literal">true</span>,</div><div class="line">	skipWaiting: <span class="literal">true</span></div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<h3 id="ts打包配置"><a href="#ts打包配置" class="headerlink" title="ts打包配置"></a>ts打包配置</h3><p>打包ts文件的时候，需要在项目根目录下创建一个名为tsconfig.json的文件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install @types/lodash --save-dev</div></pre></td></tr></table></figure></p>
<h3 id="eslint"><a href="#eslint" class="headerlink" title="eslint"></a>eslint</h3><p><a href="https://eslint.org/" target="_blank" rel="external">eslint</a><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">npm install eslint --save-dev</div><div class="line">npx eslint --init</div></pre></td></tr></table></figure></p>
<p>检测src下面的代码符不符合规范要求<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npx eslint src</div></pre></td></tr></table></figure></p>
<p>babel-eslint是较常用的eslint解析器，为了避免团队成员使用不同的编辑器导致的eslint检测区别，可以使用eslint-loader<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install eslint-loader --save-dev</div></pre></td></tr></table></figure></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">module</span>:&#123;</div><div class="line">    rules:[</div><div class="line">         &#123;</div><div class="line">            test:<span class="regexp">/\.js$/</span>,</div><div class="line">            use:[<span class="string">'babel-loader'</span>,eslint-loader]     <span class="comment">//loader执行顺序从后往左</span></div><div class="line">         &#125;</div><div class="line">    ]</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>加完之后可以在webpack.config.js的devServer加入<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">overlay: <span class="literal">true</span></div></pre></td></tr></table></figure></p>
<p>这样npm run dev的时候一旦出现eslint的问题，就会在浏览器上弹窗出打包遇到的问题</p>
<h3 id="webpack性能优化"><a href="#webpack性能优化" class="headerlink" title="webpack性能优化"></a>webpack性能优化</h3><p>提升打包速度</p>
<h4 id="跟上技术的迭代-升级webpack，npm-yarn-node"><a href="#跟上技术的迭代-升级webpack，npm-yarn-node" class="headerlink" title="跟上技术的迭代   升级webpack，npm|yarn|node"></a>跟上技术的迭代   升级webpack，npm|yarn|node</h4><h4 id="尽可能少的模块使用loader"><a href="#尽可能少的模块使用loader" class="headerlink" title="尽可能少的模块使用loader"></a>尽可能少的模块使用loader</h4><p>将this指向window的配置<br>test:/.js$/,<br>exclude:/node_module/,<br>use:[“import-loader?this=&gt;window”]</p>
<h4 id="Plugin尽可能精简并确保可靠"><a href="#Plugin尽可能精简并确保可靠" class="headerlink" title="Plugin尽可能精简并确保可靠"></a>Plugin尽可能精简并确保可靠</h4><h4 id="插件DellPlugin提高打包速率"><a href="#插件DellPlugin提高打包速率" class="headerlink" title="插件DellPlugin提高打包速率"></a>插件DellPlugin提高打包速率</h4><p>每次打包的时候比如react，react-dom.lodash的代码都是不会变的，所以只在第一次打包的时候去分析，理想的打包状态<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</div><div class="line"></div><div class="line"><span class="built_in">module</span>.exports = &#123;</div><div class="line">  entry: &#123;</div><div class="line">    vendors: [<span class="string">'react'</span>, <span class="string">'react-dom'</span>, <span class="string">'lodash'</span>]</div><div class="line">  &#125;,</div><div class="line">  output: &#123;</div><div class="line">    filename: <span class="string">'[name].dell.js'</span>,</div><div class="line">    path: path.resolve(__dirname, <span class="string">'../dell'</span>)</div><div class="line">  &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>单独生成的dell下面的vendors.dell.js这么来用<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install add-asset-html-webpack-plugin --save</div></pre></td></tr></table></figure></p>
<p>这个插件是往html里面再去增加静态资源<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">new</span> AddAssetWebpackPlugin(&#123;</div><div class="line">  filepath: path.resolve(__dirname, <span class="string">'../dell/vendors.dell.js'</span>),</div><div class="line">&#125;),</div></pre></td></tr></table></figure></p>
<p>分析打包文件，然后生成打包的映射<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">entry: &#123;</div><div class="line">    vendors: [<span class="string">'lodash'</span>],</div><div class="line">    react: [<span class="string">'react'</span>, <span class="string">'react-dom'</span>],</div><div class="line">  &#125;,</div></pre></td></tr></table></figure></p>
<p>DllPlugin生成映射<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">new</span> webpack.DllPlugin(&#123;</div><div class="line">  name: <span class="string">'[name]'</span>,</div><div class="line">  path: path.resolve(__dirname, <span class="string">'../dell/[name].manifast.json'</span>),</div><div class="line">&#125;),</div><div class="line"><span class="string">``</span><span class="string">`   </span></div><div class="line"><span class="string">然后配置AddAssetWebpackPlugin，将它加入到html中</span></div><div class="line"><span class="string">`</span><span class="string">``</span>javascript</div><div class="line"><span class="keyword">new</span> AddAssetWebpackPlugin(&#123;</div><div class="line">  filepath: path.resolve(__dirname, <span class="string">'../dell/vendors.dell.js'</span>),</div><div class="line">&#125;),</div><div class="line"><span class="keyword">new</span> AddAssetWebpackPlugin(&#123;</div><div class="line">  filepath: path.resolve(__dirname, <span class="string">'../dell/react.dell.js'</span>),</div><div class="line">&#125;),</div><div class="line"><span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</div><div class="line">  manifest: path.resolve(__dirname, <span class="string">'../dell/vendors.manifast.json'</span>),</div><div class="line">&#125;),</div><div class="line"><span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</div><div class="line">  manifest: path.resolve(__dirname, <span class="string">'../dell/react.manifast.json'</span>),</div><div class="line">&#125;),</div></pre></td></tr></table></figure></p>
<p>这么配置之后，它会去dell/vendors.manifast.json中查找第三方模块的映射关系，如果能找到就不去打包，直接从vendors.dell.js引入（从全局变量里面拿),当需要分解的文件太多的时候，为了避免每个都要复制，可以用fs来动态加载<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> files = fs.readdirSync(path.resolve(__dirname, <span class="string">'../dell'</span>));</div><div class="line"><span class="keyword">const</span> plugins = [</div><div class="line">  <span class="keyword">new</span> HTMLWebpackPlugin(&#123;</div><div class="line">    template: <span class="string">'./src/index.html'</span>,</div><div class="line">  &#125;),</div><div class="line">];</div><div class="line">files.forEach(<span class="function">(<span class="params">file</span>) =&gt;</span> &#123;</div><div class="line">  <span class="keyword">if</span> (<span class="regexp">/.*\.dell.js/</span>.test(file)) &#123;</div><div class="line">    plugins.push(<span class="keyword">new</span> AddAssetWebpackPlugin(&#123;</div><div class="line">      filepath: path.resolve(__dirname, <span class="string">'../dell'</span>, file),</div><div class="line">    &#125;));</div><div class="line">  &#125;</div><div class="line">  <span class="keyword">if</span> (<span class="regexp">/.*\.manifast.json/</span>.test(file)) &#123;</div><div class="line">    plugins.push(<span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</div><div class="line">      manifest: path.resolve(__dirname, <span class="string">'../dell'</span>, file),</div><div class="line">    &#125;));</div><div class="line">  &#125;</div><div class="line">&#125;);</div></pre></td></tr></table></figure></p>
<p>DellPlugin的打包逻辑就是项目中引入比如jquery,lodash等不会改变的静态资源的时候，就直接根据entry设置的文件名打包到dell目录下然后生成映射，后面每次打包就可以直接去dell目录下加载相关资源，不需要重新打包</p>
<h4 id="控制包大小"><a href="#控制包大小" class="headerlink" title="控制包大小"></a>控制包大小</h4><h4 id="thread-loader-parallel-webpack-happypack多进程打包（利用node里面的多进程，使用多个cpu）"><a href="#thread-loader-parallel-webpack-happypack多进程打包（利用node里面的多进程，使用多个cpu）" class="headerlink" title="thread-loader,parallel-webpack,happypack多进程打包（利用node里面的多进程，使用多个cpu）"></a>thread-loader,parallel-webpack,happypack多进程打包（利用node里面的多进程，使用多个cpu）</h4><h4 id="合理使用sourceMap"><a href="#合理使用sourceMap" class="headerlink" title="合理使用sourceMap"></a>合理使用sourceMap</h4><h4 id="综合stats分析打包结果"><a href="#综合stats分析打包结果" class="headerlink" title="综合stats分析打包结果"></a>综合stats分析打包结果</h4><h4 id="开发环境内存编译"><a href="#开发环境内存编译" class="headerlink" title="开发环境内存编译"></a>开发环境内存编译</h4><h3 id="打包多页面，"><a href="#打包多页面，" class="headerlink" title="打包多页面，"></a>打包多页面，</h3><p>一般都是单页面，也就是只有一个html的页面，要打包多个页面的时候，在entry里头写两个入口<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">entry:&#123;</div><div class="line">   main:<span class="string">'./src/index.js'</span>,</div><div class="line">   list:<span class="string">'./src/list.js'</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>然后可以去github上查找html-webpack-plugin的配置项,或者往上翻<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">new</span> HTMLWebpackPlugin(&#123;</div><div class="line">	template: <span class="string">'./src/index.html'</span>,</div><div class="line">	filename: <span class="string">'index.html'</span>,</div><div class="line">	chunks: [<span class="string">'runtime'</span>, <span class="string">'vendors'</span>, <span class="string">'main'</span>],</div><div class="line">&#125;),</div><div class="line"><span class="keyword">new</span> HTMLWebpackPlugin(&#123;</div><div class="line">	template: <span class="string">'./src/index.html'</span>,</div><div class="line">	filename: <span class="string">'list.html'</span>,</div><div class="line">	chunks: [<span class="string">'runtime'</span>, <span class="string">'vendors'</span>, <span class="string">'list'</span>],</div><div class="line">&#125;),</div><div class="line">...</div></pre></td></tr></table></figure></p>
<p>如果觉得每次这样复制不太友好，可以用封装一个函数来解决<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> makePlagins = <span class="function">(<span class="params">configs</span>) =&gt;</span> &#123;</div><div class="line">  <span class="keyword">const</span> plugins = [</div><div class="line">    <span class="comment">// new CleanWebpackPlugin(['dist'], &#123;</span></div><div class="line">    <span class="comment">//   root: path.resolve(__dirname, '../'),</span></div><div class="line">    <span class="comment">// &#125;),</span></div><div class="line">  ];</div><div class="line"></div><div class="line">  <span class="keyword">const</span> keys = <span class="built_in">Object</span>.keys(configs.entry);</div><div class="line">  keys.forEach(<span class="function">(<span class="params">item</span>) =&gt;</span> &#123;</div><div class="line">    plugins.push(</div><div class="line">      <span class="keyword">new</span> HTMLWebpackPlugin(&#123;</div><div class="line">        template: <span class="string">'./src/index.html'</span>,</div><div class="line">        filename: <span class="string">`<span class="subst">$&#123;item&#125;</span>.html`</span>,</div><div class="line">        chunks: [<span class="string">'runtime'</span>, <span class="string">'vendors'</span>, item],</div><div class="line">      &#125;),</div><div class="line">    );</div><div class="line">  &#125;);</div><div class="line"></div><div class="line">  <span class="keyword">const</span> files = fs.readdirSync(path.resolve(__dirname, <span class="string">'../dell'</span>));</div><div class="line">  files.forEach(<span class="function">(<span class="params">file</span>) =&gt;</span> &#123;</div><div class="line">    <span class="keyword">if</span> (<span class="regexp">/.*\.dell.js/</span>.test(file)) &#123;</div><div class="line">      plugins.push(<span class="keyword">new</span> AddAssetWebpackPlugin(&#123;</div><div class="line">        filepath: path.resolve(__dirname, <span class="string">'../dell'</span>, file),</div><div class="line">      &#125;));</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">if</span> (<span class="regexp">/.*\.manifast.json/</span>.test(file)) &#123;</div><div class="line">      plugins.push(<span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</div><div class="line">        manifest: path.resolve(__dirname, <span class="string">'../dell'</span>, file),</div><div class="line">      &#125;));</div><div class="line">    &#125;</div><div class="line">  &#125;);</div><div class="line"></div><div class="line">  <span class="keyword">return</span> plugins;</div><div class="line">&#125;;</div></pre></td></tr></table></figure></p>
<p>在这个操作之前先将<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">module</span>.exports=&#123;</div><div class="line">    entry:&#123;</div><div class="line">        ....</div><div class="line">    &#125;,</div><div class="line">    output:&#123;</div><div class="line">        ...</div><div class="line">    &#125;,</div><div class="line">    plugins:&#123;</div><div class="line">        ...</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>改成<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> configs=&#123;</div><div class="line">    entry:&#123;</div><div class="line">        ....</div><div class="line">    &#125;,</div><div class="line">    output:&#123;</div><div class="line">        ...</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>configs.plugins = makePlagins(configs)<br>这样就可以实现动态改变打包的入口文件就可以生成新的一个页面</p>
<h3 id="如何编写一个loader"><a href="#如何编写一个loader" class="headerlink" title="如何编写一个loader"></a>如何编写一个loader</h3><p><a href="https://www.webpackjs.com/api/" target="_blank" rel="external">webpack API</a><br>写一个loader来做异常捕获<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">const</span> loaderUtils = <span class="built_in">require</span>(<span class="string">'loader-utils'</span>)</div><div class="line"><span class="built_in">module</span>.exports = <span class="function"><span class="keyword">function</span> (<span class="params">source</span>) </span>&#123;</div><div class="line">  <span class="comment">//异常捕获start</span></div><div class="line">  <span class="keyword">try</span>(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"></div><div class="line">  &#125;).catch(e)&#123;&#125;</div><div class="line">  <span class="comment">//异常捕获end</span></div><div class="line"></div><div class="line">  <span class="keyword">const</span> options = loaderUtils.getOptions(<span class="keyword">this</span>)</div><div class="line">  <span class="keyword">const</span> callback = <span class="keyword">this</span>.async()</div><div class="line"></div><div class="line">  setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</div><div class="line">    <span class="keyword">const</span> result = source.replace(<span class="string">'hardy'</span>, options.name)</div><div class="line">    callback(<span class="literal">null</span>, result)</div><div class="line">  &#125;, <span class="number">1000</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>也可以用来写国际化<br>比如业务代码index.js中<br>console.log(‘webpack4.x‘)<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">loader里头这么写</div><div class="line"><span class="keyword">const</span> loaderUtils = <span class="built_in">require</span>(<span class="string">'loader-utils'</span>)</div><div class="line"><span class="built_in">module</span>.exports = <span class="function"><span class="keyword">function</span> (<span class="params">source</span>) </span>&#123;</div><div class="line">  <span class="keyword">if</span> (node全局变量 === <span class="string">'中文'</span>) &#123;</div><div class="line">    source.replace(<span class="string">'&#123;&#123;title&#125;&#125;'</span>, <span class="string">'中文标题'</span>)</div><div class="line">  &#125; <span class="keyword">else</span> &#123; </div><div class="line">    source.replace(<span class="string">'&#123;&#123;title&#125;&#125;'</span>,<span class="string">'english title'</span>)</div><div class="line">  &#125;</div><div class="line"></div><div class="line">  <span class="keyword">const</span> options = loaderUtils.getOptions(<span class="keyword">this</span>)</div><div class="line">  <span class="keyword">const</span> callback = <span class="keyword">this</span>.async()</div><div class="line"></div><div class="line">  setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</div><div class="line">    <span class="keyword">const</span> result = source.replace(<span class="string">'hardy'</span>, options.name)</div><div class="line">    callback(<span class="literal">null</span>, result)</div><div class="line">  &#125;, <span class="number">1000</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<h3 id="编写一个plugin"><a href="#编写一个plugin" class="headerlink" title="编写一个plugin"></a>编写一个plugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="string">"scripts"</span>: &#123;</div><div class="line">   <span class="string">"debug"</span>: <span class="string">"node --inspect --inspect-brk node_modules/webpack/bin/webpack.js"</span>,   <span class="comment">//使用node的调试工具调试插件，--inspect开启调试工具，--inspect-brk在第一行打断点</span></div><div class="line">   <span class="string">"build"</span>: <span class="string">"webpack"</span></div><div class="line"> &#125;,</div></pre></td></tr></table></figure>
<p>最近拿了新offer，今天也是国庆，祖国70周年的生日！！！</p>
<p>分享一张觉得拍的不错的美图。<br><figure class="image-bubble">
                <div class="img-lightbox">
                    <div class="overlay"></div>
                    <img src="/images/webpack/1.jpg" alt="红线" title="">
                </div>
                <div class="image-caption">红线</div>
            </figure></p>

        </div>

        <blockquote class="post-copyright">
    <div class="content">
        
<span class="post-time">
    最后更新时间：<time datetime="2020-01-13T15:27:58.144Z" itemprop="dateUpdated">2020-01-13 23:27:58</time>
</span><br>


        
        谢谢浏览，我会继续努力的，示例：<a href="/2019/09/30/webpack4-x/" target="_blank" rel="external">http://yoursite.com/2019/09/30/webpack4-x/</a>
        
    </div>
    <footer>
        <a href="http://yoursite.com">
            <img src="/img/avatar.jpg" alt="BingZhenhuang">
            BingZhenhuang
        </a>
    </footer>
</blockquote>

        
<div class="page-reward">
    <a id="rewardBtn" href="javascript:;" class="page-reward-btn waves-effect waves-circle waves-light">赏</a>
</div>



        <div class="post-footer">
            
	<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/webpack/">webpack</a></li></ul>


            
<div class="page-share-wrap">
    

<div class="page-share" id="pageShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://yoursite.com/2019/09/30/webpack4-x/&title=《webpack4.x》 — 小方块 - hhardyy.com&pic=http://yoursite.com/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://yoursite.com/2019/09/30/webpack4-x/&title=《webpack4.x》 — 小方块 - hhardyy.com&source=webpack4.x =&gt; vue.config.js但是 !== vue.config.js
" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://yoursite.com/2019/09/30/webpack4-x/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《webpack4.x》 — 小方块 - hhardyy.com&url=http://yoursite.com/2019/09/30/webpack4-x/&via=http://yoursite.com" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://yoursite.com/2019/09/30/webpack4-x/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>



    <a href="javascript:;" id="shareFab" class="page-share-fab waves-effect waves-circle">
        <i class="icon icon-share-alt icon-lg"></i>
    </a>
</div>



        </div>
    </div>

    
<nav class="post-nav flex-row flex-justify-between">
  
    <div class="waves-block waves-effect prev">
      <a href="/2019/11/08/如何简单粗暴生成条码和二维码/" id="post-prev" class="post-nav-link">
        <div class="tips"><i class="icon icon-angle-left icon-lg icon-pr"></i> Prev</div>
        <h4 class="title">如何简单粗暴生成条码和二维码</h4>
      </a>
    </div>
  

  
    <div class="waves-block waves-effect next">
      <a href="/2019/08/31/vue-echarts-vant-demo/" id="post-next" class="post-nav-link">
        <div class="tips">Next <i class="icon icon-angle-right icon-lg icon-pl"></i></div>
        <h4 class="title">Vue+echarts+vant demo</h4>
      </a>
    </div>
  
</nav>



    














</article>

<div id="reward" class="page-modal reward-lay">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <h3 class="reward-title">
        <i class="icon icon-quote-left"></i>
        🤠 请我喝可乐！
        <i class="icon icon-quote-right"></i>
    </h3>
    <div class="reward-content" style="width:50%">
        
        <div class="reward-code" style="text-align:center">
            <div style="width:300px;margin:0px auto;">
               <img id="rewardCode" style="width:50%;height:60%;display:block; margin:0px auto;" src="/img/alipay.jpg" alt="支付宝打赏二维码">
               <span style="display:inline-block; margin-bottom:20px;">0.88(支付宝 aliPay)</span>
               <img id="rewardCode" style="width:50%;height:60%;display:block; margin:0px auto;" src="/img/wechat.jpg" alt="微信打赏二维码">
               <span style="display:inline-block;">0.88(微信 weChat)</span>
            </div>
        </div>
    </div>
</div>



</div>

        <script>
!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){t&&t(),i(e)}}function i(e){var a=t.createElement("div");a.className="heart",d.push({el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){var a=t.createElement("style");a.type="text/css";try{a.appendChild(t.createTextNode(e))}catch(t){a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)}}(),n()}(window,document);
</script>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script>
    function secondToDate(second) {
        if (!second) {
            return 0;
        }
        var time = new Array(0, 0, 0, 0, 0);
        if (second >= 365 * 24 * 3600) {
            time[0] = parseInt(second / (365 * 24 * 3600));
            second %= 365 * 24 * 3600;
        }
        if (second >= 24 * 3600) {
            time[1] = parseInt(second / (24 * 3600));
            second %= 24 * 3600;
        }
        if (second >= 3600) {
            time[2] = parseInt(second / 3600);
            second %= 3600;
        }
        if (second >= 60) {
            time[3] = parseInt(second / 60);
            second %= 60;
        }
        if (second > 0) {
            time[4] = second;
        }
        return time;
    }</script>
<script type="text/javascript" language="javascript">
    function setTime() {
        var create_time = Math.round(new Date(Date.UTC(2017, 08, 18, 11, 42, 23)).getTime() / 1000);
        var timestamp = Math.round((new Date().getTime() + 8 * 60 * 60 * 1000) / 1000);
        currentTime = secondToDate((timestamp - create_time));
        currentTimeHtml = 'Running：' + currentTime[0] + '年 ' + currentTime[1] + '天 '
                + currentTime[2] + '时 ' + currentTime[3] + '分 ' + currentTime[4]
                + '秒';
        document.getElementById("htmer_time").innerHTML = currentTimeHtml;
    }    setInterval(setTime, 1000);
</script>
<footer class="footer">
    <div class="top">
        

        <p>
          <span id="busuanzi_container_page_pv">
             [&nbsp;浏览量：&nbsp;<span id="busuanzi_value_page_pv"></span>&nbsp;]
          </span>
        </p>
    </div>
    <div class="bottom">
        <p>
        <span>BingZhenhuang &copy; 2017 - 2020</span>
            <span>
                
                Power by <a href="https://hhardyy.github.io/" target="_blank">zhen On August 8</a> 
            </span>
            <span id="htmer_time" "></span>
        </p>
    </div>
</footer>

    </main>
    <div class="mask" id="mask"></div>
<a href="javascript:;" id="gotop" class="waves-effect waves-circle waves-light"><span class="icon icon-lg icon-chevron-up"></span></a>



<div class="global-share" id="globalShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://yoursite.com/2019/09/30/webpack4-x/&title=《webpack4.x》 — 小方块 - hhardyy.com&pic=http://yoursite.com/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://yoursite.com/2019/09/30/webpack4-x/&title=《webpack4.x》 — 小方块 - hhardyy.com&source=webpack4.x =&gt; vue.config.js但是 !== vue.config.js
" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://yoursite.com/2019/09/30/webpack4-x/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《webpack4.x》 — 小方块 - hhardyy.com&url=http://yoursite.com/2019/09/30/webpack4-x/&via=http://yoursite.com" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://yoursite.com/2019/09/30/webpack4-x/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>


<div class="page-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <img src="" alt="微信分享二维码">
</div>




    <script src="//cdn.bootcss.com/node-waves/0.7.4/waves.min.js"></script>
<script>
var BLOG = { ROOT: '/', SHARE: true, REWARD: true };


</script>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/main.min.js"></script>


<div class="search-panel" id="search-panel">
    <ul class="search-result" id="search-result"></ul>
</div>
<template id="search-tpl">
<li class="item">
    <a href="{path}" class="waves-block waves-effect">
        <div class="title ellipsis" title="{title}">{title}</div>
        <div class="flex-row flex-middle">
            <div class="tags ellipsis">
                {tags}
            </div>
            <time class="flex-col time">{date}</time>
        </div>
    </a>
</li>
</template>

<script src="//unpkg.com/hexo-theme-material-indigo@latest/js/search.min.js" async></script>








<script>
(function() {
    var OriginTitile = document.title, titleTime;
    document.addEventListener('visibilitychange', function() {
        if (document.hidden) {
            document.title = '(•‾̑⌣‾̑•)✧˖°回来看我';
            clearTimeout(titleTime);
        } else {
            document.title = '(゜-゜)つロ欢迎回来';
            titleTime = setTimeout(function() {
                document.title = OriginTitile;
            },2000);
        }
    });
})();
</script>



</body>
</html>
